package main

import (
	"bytes"
	"fmt"
	"os"
	"path"
	"runtime"
	"sort"
	"strings"
	"text/template"

	"github.com/sethvargo/ratchet/command"
	"github.com/sethvargo/ratchet/parser"
)

func main() {
	if err := realMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(1)
	}
}

func realMain() error {
	topLevelHelp := buildTopLevelHelp()

	tmpl, err := template.New("gen").Parse(tmpl)
	if err != nil {
		return fmt.Errorf("failed to parse template: %w", err)
	}

	var w bytes.Buffer
	if err := tmpl.Execute(&w, &Params{
		TopLevelHelp: topLevelHelp,
	}); err != nil {
		return fmt.Errorf("failed to execute template: %w", err)
	}

	root := folderRoot()
	pth := path.Join(root, "command_gen.go")
	if err := os.WriteFile(pth, w.Bytes(), 0o600); err != nil {
		return fmt.Errorf("failed to write generated file: %w", err)
	}

	return nil
}

func folderRoot() string {
	_, filename, _, _ := runtime.Caller(0)
	for range 3 {
		filename = path.Dir(filename)
	}
	return filename
}

func buildTopLevelHelp() string {
	var w strings.Builder

	commands := make(map[string]command.Command, len(command.Commands))
	for name, command := range command.Commands {
		// Ignore hidden commands
		if _, ok := command.(interface{ Hidden() }); ok {
			continue
		}

		commands[name] = command
	}

	longest := 0
	names := make([]string, 0, len(commands))
	for name := range commands {
		names = append(names, name)
		if l := len(name); l > longest {
			longest = l
		}
	}
	sort.Strings(names)

	fmt.Fprint(&w, "Usage: ratchet COMMAND\n\n")
	for _, name := range names {
		cmd := command.Commands[name]

		padding := strings.Repeat(" ", longest-len(name)+4)
		fmt.Fprintf(&w, "  %s%s%s\n", name, padding, cmd.Desc())
	}

	parsers := parser.List()
	if len(parsers) > 0 {
		fmt.Fprintf(&w, "\nAvailable parsers:\n\n")
		for _, name := range parser.List() {
			fmt.Fprintf(&w, "  %s\n", name)
		}
	}

	return w.String()
}

type Params struct {
	TopLevelHelp string
}

const tmpl = `// Code generated by "command/cmd/gen". DO NOT EDIT.

package command

const topLevelHelp = ` + "`" + `{{.TopLevelHelp}}` + "`" + `
`
